"""
按周期计算收益率，简单方法
"""
import pandas as pd
import numpy as np
from scipy.stats import percentileofscore
from research.calcor import calcor_base

class box_zoom(calcor_base):
    def __init__(self,timeperiod=60,mintimeperiod=None,box=None):
        super().__init__(timeperiod=timeperiod,mintimeperiod=mintimeperiod,datatype="dim1")
        self.box=box
    def calc(self):
        f=pd.Series(data=self.hisdata)
        f.sort_values(inplace=True)
        f1=f.isna()
        n=len(f)+1
        f=pd.Series(data=list(range(1,n)),index=f.index)
        f.loc[f1] = np.nan
        if self.box:
            min0=f.min()
            max0=f.max()
            f=(f-min0)/(max0-min0)
            if self.box !=[0,1]:
                f=f*(self.box[1]-self.box[0])+self.box[0]
        return f
class binning_eqdistance(calcor_base):
    def __init__(self,timeperiod=300,mintimeperiod=None,bins=5):
        super().__init__(timeperiod=timeperiod,mintimeperiod=mintimeperiod,datatype="dim1")
        self.bins=bins
    def calc(self):
        data=self.hisdata
        d=data[-1]
        r0=min(data)
        r1=max(data)
        delta=(r1-r0)/self.bins
        rst=int((d-r0)/delta)+1
        if rst>self.bins:
            rst=self.bins
        return rst
class binning_eqfreq(calcor_base):
    def __init__(self,timeperiod=300,mintimeperiod=None,bins=5):
        super().__init__(timeperiod=timeperiod,mintimeperiod=mintimeperiod,datatype="dim1")
        self.bins=bins
        self.bins0=100/bins
    def calc(self):
        data=self.hisdata
        r = percentileofscore(data, data[-1])
        rst=int(r/self.bins0)+1
        if rst>self.bins:
            rst=self.bins
        return rst
class box_zoom_byobjs:
    def __init__(self,box=None):
        self.box=box
    def oncalc(self,d,timekey=None):
        f=d.copy()
        f.sort_values(inplace=True)
        f1=f.isna()
        n=len(f)+1
        f=pd.Series(data=list(range(1,n)),index=f.index)
        f.loc[f1] = np.nan
        if self.box:
            min0=f.min()
            max0=f.max()
            f=(f-min0)/(max0-min0)
            if self.box !=[0,1]:
                f=f*(self.box[1]-self.box[0])+self.box[0]
        return f
#
class binning_eqdistance_byobjs:
    def __init__(self,bins=5):
        self.bins=bins
        self.data=[]
    def oncalc(self,d,timekey=None):
        r0=d.min()
        r1=d.max()
        delta=(r1-r0)/self.bins
        rst=int((d-r0)/delta)+1
        if rst>self.bins:
            rst=self.bins
        return rst
class binning_eqfreq_byobjs:
    def __init__(self,bins=5):
        self.bins=bins
        self.data=[]
        self.bins0=100/bins
    def oncalc(self,d,timekey=None):
        r = percentileofscore(self.data, self.data[-1])
        rst=int(r/self.bins0)+1
        if rst>self.bins:
            rst=self.bins
        return rst

